let str:string = "你好 ts！";

let blo:boolean = false;

// 数组
let arr1:number[] = [1, 2, 3, 4];
let arr2:any[] = [1, 2, 3, 4, "123", false];
// 泛型数组
let arrTest1:Array<number> = [123];
let arrTest2:Array<any> = [1, "2"];
// 元组
let arrTuple:[String, Number, Boolean] = ['str', 123, true];
// 怎么定义二维数组呢？

// 枚举类型
enum Flag {success = 1, error = 2};
console.log(Flag.success);
// 枚举item无值时，会输出item对应index
enum Color {red, green, yellow};
let b = Color.green;
console.log(b);

enum Index {index1, index2 = 'str', index3 = '1str'};
let index = Index.index1;
console.log(typeof index);

// let oNever:never;
// oNever = (()  => {
//   throw new Error('Error');
// })();

console.log('123')
// 函数定义
function fun (a:number, b:number, c:number=12):number {
  return a+b+c;
}
// alert(fun(1, 2, 4))

function funFor (a:number, ...results:number[]):number {
  let sum = 0;
  for(let i=0;i<results.length;i++){
    sum += results[i];
  }
  return sum
}
// alert(funFor(1,2,3,4,5,6,7,8,9))

// ----------------

// ts定义类
class Person {
  name: string;
  constructor (n:string) {
    this.name = n
  }
  // run():void{
  //   alert(this.name)
  // }
  getName():string{
    return `${this.name}在动次打次`;
  }
  setName(name:string):void{
    this.name = name;
  }
}
let nP = new Person('张三');
// nP.run();
// alert(nP.getName());
nP.setName('毛利里斯');
// alert(nP.getName());

// ----------------

// ts中实现继承extends、super
class People extends Person {
  // 即使这样能继承父类，但实际上是错误写法，祥见SonBrother
}
let Sonobj = new People('士大夫');
// alert(Sonobj.getName());

class SonBrother extends Person {
  constructor(name:string){
    super(name)
  }
  run():string{
    return `${this.name}在biubiubiu`
  }
}
let SB = new SonBrother('铝合金');
// alert(SB.getName());
// alert(SB.run());

// ----------------

// 类修饰符 typescript中提供了三种修饰符（默认public）
/*
  public      公有        在类里面、子类、类外均可访问
  protected   保护类型    在类里面、子类可访问，类外不可访问
  private     私有        类里可访问，子类、类外不可访问
*/
class Parent {
  public name: string;
  constructor (n:string) {
    this.name = n
  }
}
class Son extends Parent {
  constructor(name:string){
    super(name)
  }
  work():string{
    return this.name
  }
}
let son = new Parent('我是pulic')
// alert(son.name)

// ----------------

// 静态属性、静态方法
class staticObj{
  public typeTest:string
  static typeName:string = "静态数据";
  constructor(type:string){
    this.typeTest = type;
  }
  static print(){
    // alert('print方法'+this.typeName)
  }
}
staticObj.print();
// alert(staticObj.typeName)

// ----------------

// 多态
class Animal {
  name:string;
  constructor(name:string){
    this.name = name;
  }
  eat(){
    console.log("吃东西");
  }
}
class Dog extends Animal {
  constructor(name:string){
    super(name);
  }
  eat(){
    return this.name + '吃骨头';
  }
}
class Cat extends Animal {
  constructor(name:string){
    super(name);
  }
  eat(){
    return this.name + '吃鱼';
  }
}

// ----------------

// 抽象类，是提供其子类所继承的基类，不能直接实例化，并且其子类必须定义此抽象类
// abstract抽象类，标准：Animal这个类的子类必须包含eat方法，即抽象类和抽象方法用来定义标准
abstract class absAnimal {
  public name:string;
  constructor(name:string){
    this.name = name;
  }
  abstract eat():any;
}
// 父类中定义抽象类方法eat，子类必须具有此方法
class absDog extends absAnimal {
  constructor(name:string){
    super(name)
  }
  eat(){
    console.log(this.name + "吃骨头")
  }
}
let AD = new absDog("黑子");
AD.eat()
class absCat extends absAnimal {
  constructor(name:string){
    super(name)
  }
  eat(){
    console.log(this.name + "吃鱼")
  }
}
let AC = new absCat("咪咪");
AC.eat()

// ----------------

// 接口
// json约束
function constraintJson (labelInfo:{label:string}):void{
  alert(labelInfo.label);
}
// constraintJson({label: '限制'});
// 批量约束
interface Fullname{
  firstNamt:string;
  lastName:string;
  age?:number   // 接口：可选属性
}
function printName (name:Fullname):void {
  // alert(name.firstNamt + "---" + name.lastName)
}
let oObj = {
  firstNamt: "李",
  lastName: "四",
  age:20,
  sex:"男"
};
printName(oObj);

// 定义ajax
interface Config{
  type:string;
  url:string;
  data?:string;
  dataType:string;
}
function ajax(config:Config):void{
  let xhr = new XMLHttpRequest();
  xhr.open(config.type, config.url, true);
  xhr.send(config.data);
  xhr.onreadystatechange = function () {
    if(xhr.readyState === 4 && xhr.status === 200){
      console.log("change");
      if(config.dataType === "json"){
        console.log("JSON：", JSON.parse(xhr.responseText));
      }else{
        console.log(xhr.responseText)
      }
    }
  }
}
ajax({
  type: "get",
  url: "http://a.itying.com/api/productlist",
  data:"name=zhangsan",
  dataType:"json"
})

// 函数类型接口：对方法传入的参数以及返回值进行约束

interface UserArr{
  [index:number]:string
}

// 可索引接口
interface UserObj{
  [index:string]:string
}
let arr:UserObj = {name:"在jam萨满"}

// 类类型接口
interface IntfAnimal{
  name:string;
  eat(str:string):void;
}
class Pig implements IntfAnimal {
  name:string;
  constructor(name:string){
    this.name = name;
  }
  eat() {
    console.log(this.name + "吃🐖食");
  }
}
let d = new Pig("猪猪侠")
d.eat();

// 接口继承接口
interface dAnimal{
  eat():void;
}
interface dDog extends dAnimal{
  work():void;
}
class Programmer {
  public name:string
  constructor(name:string){
    this.name = name
  }
  codding(code:string){
    console.log(this.name + code)
  }
}
// 继承类并且实现接口
class dWeb extends Programmer implements dDog{ //implements实现接口
  // public name:string;
  constructor(name:string){
    // this.name = name;
    super(name);
  }
  eat(){
    console.log(this.name + "吃大骨头~！")
  }
  work(){
    console.log(this.name + "汪汪汪~！")
  }
}
let DDog = new dWeb("大黄")
DDog.eat();
DDog.work();
DDog.codding("写ts汪汪汪~！")

// ----------------

// 泛型
let getData = <T>(value:T):T => {
  return value;
}
getData<string>("123");
getData<number>(123);
getData<boolean>(true);

// 泛型类
class MinClass{
  public list:number[] = [];
  add(num:number){
    this.list.push(num);
  }
  min():number{
    let minNum = this.list[0];
    for(let i=0;i<this.list.length;i++){
      if(minNum>this.list[i]){
        minNum = this.list[i]
      }
    }
    return minNum;
  }
}
let testMin = new MinClass;
testMin.add(12);
testMin.add(1);
testMin.add(22);
alert("最小值：" + testMin.min());
// 升级版
class MinClassOptimize<T>{
  public list:T[] = [];
  add(value:T):void{
    this.list.push(value);
  }
  min():T{
    let minNum = this.list[0];
    for(let i=0;i<this.list.length;i++){
      if(minNum>this.list[i]){
        minNum = this.list[i];
      }
    }
    return minNum;
  }
}
// number则比较大小，string则比较ASCII码
let MinValue = new MinClassOptimize<string>();
MinValue.add('c');
MinValue.add('z');
MinValue.add('a');
alert(MinValue.min());

// 泛型接口
interface configFn{
  <T>(value:T):T;
}
let getIntfData:configFn = <T>(value:T):T => {
  return value;
}
getIntfData<string>('张三很烦');
getIntfData<number>(666);

// 类作为参数约束数据传入的类型
class User{
  userName:string | undefined;
  password:string | undefined;
}
class MysqlDb{
  add(user:User):boolean{
    console.log(user);
    return true;
  }
}
let uu = new User();
uu.userName = "周日";
uu.password = "123456";
let Db = new MysqlDb();
Db.add(uu);

// 操作数据库的泛型类
class MysqlIntf<T>{
  add(info:T):boolean{
    console.log(info);
    return true;
  }
  updata(info:T,id:number):boolean{
    console.log(info, id);
    return true;
  }
}
class AticalInfo{
  title:string | undefined;
  desc:string | undefined;
  status?:number | undefined;
  constructor(params:{
    title:string | undefined,
    desc:string | undefined,
    status?:number | undefined
  }){
    this.title = params.title;
    this.desc = params.desc;
    this.status = params.status;
  }
}
let aa = new AticalInfo({
  title: "周日",
  desc: "学习ts",
  // status: 1
});
// aa.title = "周日";
// aa.desc = "学习ts";
// aa.status = 1;
let AAMys = new MysqlIntf<AticalInfo>();
AAMys.add(aa);
AAMys.updata(aa,13);

// ----------------

// 定义一个操作数据库的库 支持Mysql Mssql MongoDb

import {MysqlDbClass, MyssqlDbClass} from "./modules/db";
import { UserClass, UserModel} from "./model/user";
// 定义类和数据库做映射
// class UserClass{
//   userName:string | undefined;
//   password:string | undefined;
// }
let uuu = new UserClass();
uuu.userName = "1111";
uuu.password = "1234566666";

// let oooMysql = new MysqlDbClass<UserClass>();
// 模块化引入后直接使用
let oooMysql = UserModel;

oooMysql.add(uuu);
console.log("获取data：",oooMysql.get(1));

let oooMyssql = new MyssqlDbClass<UserClass>();
oooMyssql.add(uuu);

// ----------------

// 模块祥见./modules